﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using YArchitech.Revit;
using StairsModuleAndEdit.StairsModel.CommonUnit;

namespace StairsModuleAndEdit.StairsModel.Manage
{
	public class StairsRunManager
	{
		public StairsRunManager(Autodesk.Revit.DB.Document doc, Stairs stairs)
		{
			this.m_Document = doc;
			this.m_Stairs = stairs;
		}

		public double GetStairsTreadHeight()
		{
			double result = 0.0;
			if (this.m_Stairs.IsValidObject)
			{
				result = this.m_Stairs.get_Parameter(BuiltInParameter.STAIRS_ACTUAL_RISER_HEIGHT).AsDouble();
			}
			return result;
		}

		public double GetStairsTreadThickness()
		{
			double result = 0.0;
			if (this.m_Stairs.IsValidObject)
			{
				try
				{
					ElementId typeId = this.m_Stairs.GetTypeId();
					StairsType stairsType = this.m_Document.GetElement(typeId) as StairsType;
					Parameter parameter = stairsType.get_Parameter(BuiltInParameter.STAIRSTYPE_RUN_TYPE);
					ElementId elementId = parameter.AsElementId();
					StairsRunType stairsRunType = this.m_Document.GetElement(elementId) as StairsRunType;
					result = stairsRunType.get_Parameter(BuiltInParameter.STAIRS_TRISERTYPE_TREAD_THICKNESS).AsDouble();
				}
				catch (Exception)
				{
				}
			}
			return result;
		}

		public double GetStairsRunRealHeight(int nRunFloorIndex)
		{
			double result = 0.0;
			try
			{
				ICollection<ElementId> stairsRuns = this.m_Stairs.GetStairsRuns();
				SortedDictionary<double, double> sortedDictionary = new SortedDictionary<double, double>();
				foreach (ElementId elementId in stairsRuns)
				{
					StairsRun stairsRun = this.m_Document.GetElement(elementId) as StairsRun;
					if (stairsRun != null)
					{
						double baseElevation = stairsRun.BaseElevation;
						double height = stairsRun.Height;
						if (!sortedDictionary.ContainsKey(baseElevation))
						{
							sortedDictionary.Add(baseElevation, height);
						}
					}
				}
				if (sortedDictionary.Count > nRunFloorIndex)
				{
					result = sortedDictionary.ElementAt(nRunFloorIndex).Value;
				}
			}
			catch (Exception)
			{
			}
			return result;
		}

		public double GetStairsRunTopElevation(int nRunFloorIndex, double dRefElevation)
		{
			double num = 0.0;
			try
			{
				ICollection<ElementId> stairsRuns = this.m_Stairs.GetStairsRuns();
				SortedDictionary<double, double> sortedDictionary = new SortedDictionary<double, double>();
				foreach (ElementId elementId in stairsRuns)
				{
					StairsRun stairsRun = this.m_Document.GetElement(elementId) as StairsRun;
					if (stairsRun != null)
					{
						double baseElevation = stairsRun.BaseElevation;
						double topElevation = stairsRun.TopElevation;
						if (!sortedDictionary.ContainsKey(baseElevation))
						{
							sortedDictionary.Add(baseElevation, topElevation);
						}
					}
				}
				if (sortedDictionary.Count > nRunFloorIndex)
				{
					num = sortedDictionary.ElementAt(nRunFloorIndex).Value;
				}
			}
			catch (Exception)
			{
			}
			return num + dRefElevation;
		}

		public double GetStairsRunRiserThickness()
		{
			double result = 0.0;
			if (this.m_Stairs.IsValidObject)
			{
				StairsRun stairsRun;
				if (!this.GetStairsRunByIndex(0, out stairsRun))
				{
					return result;
				}
				ElementId typeId = stairsRun.GetTypeId();
				StairsRunType stairsRunType = this.m_Document.GetElement(typeId) as StairsRunType;
				if (stairsRunType == null)
				{
					return result;
				}
				try
				{
					result = stairsRunType.GetParameter(BuiltInParameter.STAIRS_TRISERTYPE_RISER_THICKNESS).AsDouble();
				}
				catch
				{
				}
			}
			return result;
		}

		public bool GetStairsRunByIndex(int nRunFloorIndex, out StairsRun sRun)
		{
			bool result = false;
			sRun = null;
			if (nRunFloorIndex < 0)
			{
				return result;
			}
			ICollection<ElementId> stairsRuns = this.m_Stairs.GetStairsRuns();
			if (stairsRuns.Count > nRunFloorIndex)
			{
				ElementId elementId = stairsRuns.ElementAt(nRunFloorIndex);
				sRun = (this.m_Document.GetElement(elementId) as StairsRun);
				result = true;
			}
			return result;
		}

		public Curve GetStairsRunTopRiserEdgeCurve(XYZ vecUpStairs)
		{
			Curve result = null;
			StairsRun stairsRun = null;
			if (this.GetStairsRunByIndex(0, out stairsRun))
			{
				Face topMostPlanarFace = ElementGeometryFaceManager.GetTopMostPlanarFace(this.m_Stairs);
				if (null != topMostPlanarFace)
				{
					CurveLoop stairsPath = stairsRun.GetStairsPath();
					if (stairsPath != null)
					{
						XYZ endPoint = stairsPath.First<Curve>().GetEndPoint(1);
						Line line = Line.CreateUnbound(endPoint, vecUpStairs);
						double val = double.MinValue;
						foreach (object obj in topMostPlanarFace.EdgeLoops)
						{
							EdgeArray edgeArray = (EdgeArray)obj;
							foreach (object obj2 in edgeArray)
							{
								Edge edge = (Edge)obj2;
								Curve curve = edge.AsCurve();
								if (!(null == curve))
								{
									double z = curve.GetEndPoint(0).Z;
									Transform transform = Transform.CreateTranslation(new XYZ(0.0, 0.0, -z));
									curve = curve.CreateTransformed(transform);
									IntersectionResultArray intersectionResultArray = null;
									line.Intersect(curve, out intersectionResultArray);
									if (intersectionResultArray != null && 1 == intersectionResultArray.Size)
									{
										XYZ xyzpoint = intersectionResultArray.get_Item(0).XYZPoint;
										double num = line.Origin.DistanceTo(xyzpoint);
										if (Geometry.GreaterThan(num, val))
										{
											result = curve;
											val = num;
										}
									}
								}
							}
						}
					}
				}
			}
			return result;
		}

		private Document m_Document;

		private Stairs m_Stairs;
	}
}
